package com.jymj.service.impl;

import com.jymj.dao.SysUserDao;
import com.jymj.entity.*;
import com.jymj.service.*;
import com.jymj.utils.Constant;
import com.jymj.utils.RRException;
import com.jymj.utils.ShiroUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.apache.shiro.crypto.hash.Sha256Hash;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.system.ApplicationHome;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ResourceUtils;

import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.text.NumberFormat;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.logging.Logger;

import static com.jymj.utils.ShiroUtils.getUserId;

/**
 * 系统用户
 *
 * @author chenshun
 * @email sunlightcs@gmail.com
 * @date 2016年9月18日 上午9:46:09
 */
@Service("sysUserService")
@Slf4j
public class SysUserServiceImpl implements SysUserService {

    @Autowired
    private SysUserDao sysUserDao;
    @Autowired
    private SysUserRoleService sysUserRoleService;
    @Autowired
    private SysRoleService sysRoleService;
    @Autowired
    private SysXzqService xzqService;
    @Autowired
    private SysMenuService sysMenuService;

    @Override
    public List<String> queryAllPerms(Long userId) {
        return sysUserDao.queryAllPerms(userId);
    }

    @Override
    public List<Long> queryAllMenuId(Long userId) {
        return sysUserDao.queryAllMenuId(userId);
    }

    @Override
    public SysUserEntity queryByUserName(String username) {
        SysUserEntity sysUserEntity = sysUserDao.queryByUserName(username);
        List<SysXzqEntity> xzqList = new ArrayList<>();
        if (sysUserEntity == null) {
            return null;
        } else {
            List<PjProjEntity> pjProjEntities = sysUserRoleService.queryprojId(sysUserEntity.getUserId());
            sysUserEntity.setPjProjEntityList(pjProjEntities);

            if (sysUserEntity.getType() != null && (sysUserEntity.getType() == 1
                    || sysUserEntity.getType() == 4 || sysUserEntity.getType() == 5
            || sysUserEntity.getType() == 6)) {
                xzqList = xzqService.getUserDistrictList(sysUserEntity.getUserId());
            } else if (sysUserEntity.getType() != null && sysUserEntity.getType() == 2 ) {
                xzqList = xzqService.getUserTownList(sysUserEntity.getUserId());
            } else {
                xzqList = xzqService.getUserXzqList(sysUserEntity.getUserId());
            }
            //只有超级管理员，才能查看所有管理员列表

            if (xzqList.size() > 0) {
                if (xzqList.get(0).getCode() != null) {
                    sysUserEntity.setCode(xzqList.get(0).getCode());
                }
                if (xzqList.get(0).getName() != null) {
                    sysUserEntity.setXzqmc(xzqList.get(0).getName());
                }
                if (xzqList.get(0).getCenter() != null) {
                    sysUserEntity.setCenter(xzqList.get(0).getCenter());
                }
            }

            List<SysMenuEntity> menuList = sysMenuService.queryUserList(sysUserEntity.getUserId());
            sysUserEntity.setMenuList(menuList);
            List<SysXzqFhEntity> xzqFhEntities = new ArrayList<>();
            for (SysXzqEntity sysXzqEntity:xzqList){
                SysXzqFhEntity sysXzqFhEntity = new SysXzqFhEntity();
                sysXzqFhEntity.setXzqId(sysXzqEntity.getXzqId() == null? null : sysXzqEntity.getXzqId());
                sysXzqFhEntity.setName(sysXzqEntity.getName() == null? null : sysXzqEntity.getName());
                sysXzqFhEntity.setCode(sysXzqEntity.getCode() == null? null : sysXzqEntity.getCode());
                sysXzqFhEntity.setGeometry(sysXzqEntity.getGeometry() == null? null : sysXzqEntity.getGeometry());
                sysXzqFhEntity.setCenter(sysXzqEntity.getCenter() == null? null : sysXzqEntity.getCenter());
                xzqFhEntities.add(sysXzqFhEntity);
            }
            sysUserEntity.setXzqs(xzqFhEntities);
            return sysUserEntity;
        }
    }

    @Override
    public SysUserEntity queryObject(Long userId) {
        return sysUserDao.queryObject(userId);
    }

    @Override
    public SysUserEntity queryObjectType(Long userId) {
        return sysUserDao.queryObjectType(userId);
    }

    @Override
    public List<String> queryCodeList(Long userId) {
        return sysUserDao.queryCodeList(userId);
    }

    @Override
    public List<SysUserEntity> queryList(Map<String, Object> map) {
        return sysUserDao.queryList(map);
    }

    @Override
    public int queryTotal(Map<String, Object> map) {
        return sysUserDao.queryTotal(map);
    }

    @Override
    @Transactional(rollbackFor = RuntimeException.class)
    public void save(SysUserEntity user) {
        user.setCreateTime(new Date());
        //sha256加密
        user.setPassword(new Sha256Hash(user.getPassword()).toHex());
        sysUserDao.save(user);

        //检查角色是否越权
        //checkRole(user);

        //保存用户与角色关系
        sysUserRoleService.saveOrUpdate(user.getUserId(), user.getRoleIdList());
    }

    @Override
    @Transactional(rollbackFor = RuntimeException.class)
    public void update(SysUserEntity user) {
        if (StringUtils.isBlank(user.getPassword())) {
            user.setPassword(null);
        } else {
            user.setPassword(new Sha256Hash(user.getPassword()).toHex());
        }
        if("".equals(user.getDeviceCode())){
            user.setDeviceCode(null);
        }

        //查询是否有权限
        List<String> lists = xzqService.qeryCode(getUserId());
        if (lists.contains(user.getCode())){
            sysUserDao.update(user);
        }else {
            return;
        }

        //检查角色是否越权
        //checkRole(user);
        //保存用户与角色关系
        sysUserRoleService.saveOrUpdate(user.getUserId(), user.getRoleIdList());
    }

    @Override
    @Transactional
    public void deleteBatch(Long[] userId) {
        sysUserDao.deleteBatch(userId);
    }

    @Override
    @Transactional(rollbackFor = RuntimeException.class)
    public int updatePassword(Long userId, String password, String newPassword) {
        Map<String, Object> map = new HashMap<>();
        map.put("userId", userId);
        map.put("password", password);
        map.put("newPassword", newPassword);
        return sysUserDao.updatePassword(map);
    }

    @Override
    public List<SysUserEntity> queryAll(Long pid, Long userId) {
        Map map = new HashMap();
        map.put("pid", pid);
        map.put("userId", userId);
        return sysUserDao.queryAll(map);
    }

    @Override
    @Transactional(rollbackFor = RuntimeException.class)
    public void updateDeviceCode(SysUserEntity user) {
        sysUserDao.updateDeviceCode(user);
    }

    /**
     * 检查角色是否越权
     */
    private void checkRole(SysUserEntity user) {
        //如果不是超级管理员，则需要判断用户的角色是否自己创建
        if (user.getCreateUserId() == Constant.SUPER_ADMIN || user.getCreateUserId() == Constant.SUPER_ROOT) {
            return;
        }

        //查询用户创建的角色列表
        List<Long> roleIdList = sysRoleService.queryRoleIdList(user.getCreateUserId());

        //判断是否越权
        if (!roleIdList.containsAll(user.getRoleIdList())) {
            throw new RRException("新增用户所选角色，不是本人创建");
        }
    }

    @Override
    public List<SysUserEntity> queryRy(String code,String name) {
        Map map = new HashMap();
        map.put("code",code);
        map.put("name",name);
        map.put("sysUser",ShiroUtils.getUserEntity());
        return sysUserDao.queryRy(map);
    }

    @Override
    @Transactional(rollbackFor=RuntimeException.class)
    public void saveUser(SysUserEntity user) {
        user.setCreateTime(new Date());
        //sha256加密
        user.setPassword(new Sha256Hash(user.getPassword()).toHex());
        user.setStatus(1);
        sysUserDao.save(user);

        //判断 添加是外业 直接关联外业角色
        List<Long> roleIdList = new ArrayList<>();
        if (user.getType() == 1){
            roleIdList.add(130L);
        }else if (user.getType() == 4){
            roleIdList.add(129L);
        }else if (user.getType() == 5){
            roleIdList.add(421L);
        }else if (user.getType() == 6){
            roleIdList.add(483L);
        } else {
            //查詢角色是否已存在
            roleIdList = saveOrUpdateRole(user);
        }
        sysUserRoleService.saveOrUpdate(user.getUserId(), roleIdList);
    }

    @Override
    @Transactional(rollbackFor = RuntimeException.class)
    public void updateUser(SysUserEntity user) {
        if (StringUtils.isBlank(user.getPassword())) {
            user.setPassword(null);
        } else {
            user.setPassword(new Sha256Hash(user.getPassword()).toHex());
        }
        if("".equals(user.getDeviceCode())){
            user.setDeviceCode(null);
        }
        sysUserDao.update(user);
        //保存用户与角色关系
        //查询角色是否存在  不存在则创建
        if(user.getType() != null && user.getCode() != null && user.getXzqmc() != null){
            List<Long> roleIdList = new ArrayList<>();
            if (user.getType() == 1){
                roleIdList.add(130L);
            }else if (user.getType() == 4){
                roleIdList.add(129L);
            }else if (user.getType() == 5){
                roleIdList.add(421L);
            }else if (user.getType() == 6){
                roleIdList.add(483L);
            }else{
                roleIdList = saveOrUpdateRole(user);
            }
            sysUserRoleService.saveOrUpdate(user.getUserId(), roleIdList);
        }
    }

    @Override
    public List<SysUserEntity> getUserByMobile(String mobile) {
        List<SysUserEntity> sysUserEntities = sysUserDao.getUserByMobile(mobile);
        return sysUserEntities;
    }

    @Override
    public String getUserInfo(HttpServletResponse response, String code){
        //确定编码的格式
        response.setCharacterEncoding("UTF-8");
        //获取导出的数据
        List<SysUserEntity> sysUserEntities =  sysUserDao.getUserInfo(code);
        if (sysUserEntities.size()<1)throw new RRException("该镇/村不存在用户");
        //创建excel文件
        XSSFWorkbook xssfWorkbook = new XSSFWorkbook();
        //创建sheet页
        String fileName = "用户信息";
        XSSFSheet sheet = xssfWorkbook.createSheet(fileName);
        XSSFRow titleRow = sheet.createRow(0);
        titleRow.createCell(0).setCellValue("用户id");
        titleRow.createCell(1).setCellValue("用户名称");
        titleRow.createCell(2).setCellValue("邮箱地址");
        titleRow.createCell(3).setCellValue("手机号码");
        titleRow.createCell(4).setCellValue("创建时间");
        titleRow.createCell(5).setCellValue("用户姓名");
        titleRow.createCell(6).setCellValue("身份证号码");
        titleRow.createCell(7).setCellValue("职务");
        titleRow.createCell(8).setCellValue("所在镇");
        titleRow.createCell(9).setCellValue("所在村");
        for (SysUserEntity sysUserEntity : sysUserEntities) {
            XSSFRow dataRow = sheet.createRow(sheet.getLastRowNum() + 1);
            dataRow.createCell(0)
                    .setCellValue(sysUserEntity.getUserId()==null?"":String.valueOf(sysUserEntity.getUserId()));
            dataRow.createCell(1)
                    .setCellValue(sysUserEntity.getUsername()==null?"":sysUserEntity.getUsername());
            dataRow.createCell(2)
                    .setCellValue(sysUserEntity.getEmail()==null?"":sysUserEntity.getEmail());
            dataRow.createCell(3)
                    .setCellValue(sysUserEntity.getMobile()==null?"":sysUserEntity.getMobile());
            dataRow.createCell(4)
                    .setCellValue(sysUserEntity.getCreateTime()==null?"":new SimpleDateFormat("yyyy-MM-dd").format(sysUserEntity.getCreateTime()));
            dataRow.createCell(5)
                    .setCellValue(sysUserEntity.getName()==null?"":sysUserEntity.getName());
            dataRow.createCell(6)
                    .setCellValue(sysUserEntity.getIdcard()==null?"":sysUserEntity.getIdcard());
            dataRow.createCell(7)
                    .setCellValue(sysUserEntity.getPosition()==null?"":sysUserEntity.getPosition());
            dataRow.createCell(8)
                    .setCellValue(sysUserEntity.getZhen()==null?"":sysUserEntity.getZhen());
            dataRow.createCell(9)
                    .setCellValue(sysUserEntity.getXzqmc()==null?"":sysUserEntity.getXzqmc());
        }
        for (int i = 0; i < titleRow.getLastCellNum(); i++) {
            sheet.autoSizeColumn(i, true);
            sheet.setColumnWidth(i, sheet.getColumnWidth(i) * 15 / 10);
        }
        //获取配置文件中保存对应excel文件的路径，本地也可以直接写成F：excel/stuInfoExcel路径
        try {
            String path = new ApplicationHome(getClass()).getSource().getParentFile()+File.separator
                    +"fileupload"+ File.separator;
            String uploadPath = "excel"+ File.separator+getUserId()+ File.separator;//+File.separator+fileName
            File filePath = new File(path+uploadPath);
            if (!filePath.exists()){
                filePath.mkdirs();
                log.info("创建目录"+path+uploadPath);
            }
            String uploadFile = new SimpleDateFormat("yyyy-MM-dd").format(new Date())+fileName+".xlsx";
            String savePath = path+uploadPath+uploadFile;
            OutputStream fileOut = new FileOutputStream(savePath);
            xssfWorkbook.write(fileOut);
            log.info("生成路径为：{}",savePath);
            System.out.println(savePath);
            fileOut.close();
            xssfWorkbook.close();
            return uploadPath+uploadFile;
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;

    }

    @Override
    @Transactional(rollbackFor = RuntimeException.class)
    public void updateUserInfo(SysUserEntity sysUserEntity) {
        if (!sysUserEntity.getUserId().equals(getUserId()))
            throw new RRException("无权限更改他人账号");
        Integer rows = sysUserDao.update(sysUserEntity);
        if (rows<1)
            throw new RRException("修改的用户可能已经不存在");
    }


    public List<Long> saveOrUpdateRole(SysUserEntity user) {
        List<Long> roleIdList = new ArrayList<>();
        Map map = new HashMap();
        map.put("roleName",user.getXzqmc()+user.getCode());
        List<SysRoleEntity> sysRoleEntities = sysRoleService.queryList(map);
        if (sysRoleEntities == null || sysRoleEntities.size() == 0){
            //添加角色
            SysRoleEntity sysRoleEntity = new SysRoleEntity();
            sysRoleEntity.setRoleName(user.getXzqmc()+user.getCode());
            List<SysXzqFhEntity> xzqs = user.getXzqs();
            List<Long> xzqids = new ArrayList<>();
            for (SysXzqFhEntity sysXzqFhEntity : xzqs){
                xzqids.add(sysXzqFhEntity.getXzqId());
            }
            sysRoleEntity.setXzqIdList(xzqids);
            List<Long> menuids = new ArrayList<>();
            menuids.add(278L);
            menuids.add(279L);
            menuids.add(280L);
            menuids.add(281L);
            menuids.add(282L);
            menuids.add(17L);
            menuids.add(15L);
            if(user.getType() == 2){
                menuids.add(2L);
                menuids.add(16L);
                menuids.add(18L);
            }
            sysRoleEntity.setMenuIdList(menuids);
            sysRoleEntity.setCreateUserId(getUserId());
            sysRoleService.saveRole(sysRoleEntity);
            //保存用户与角色关系
            roleIdList.add(sysRoleEntity.getRoleId());
        }else {
            roleIdList.add(sysRoleEntities.get(0).getRoleId());
        }
        return roleIdList;
    }
}
